import axios from 'axios'
import { Toast } from 'vant'
import 'vant/es/toast/style'

import userStoreCreater from '@/store/userStore.js'
import { useRequest } from './useRequest'
const { ifCancelCurrentReq, removeRequestMap, addRequestMap, clearRequestMap } = useRequest()

const API_PREFIX = import.meta.env.VITE_API_PREFIX

const service = axios.create({
  baseURL: API_PREFIX,
  timeout: 10000,
})

// 请求前的统一处理
service.interceptors.request.use(
  (config) => {
    Toast.loading({
      message: '加载中...',
      duration: 0,
      loadingType: 'spinner',
    })
    // 检测是否存在重复请求，若存在，则取消重复的请求
    if (!ifCancelCurrentReq(config)) {
      // 不重复，把当前请求信息添加到requestMap对象中
      addRequestMap(config)
      // JWT鉴权处理
      const userStore = userStoreCreater()
      if (userStore.getToken) {
        config.headers.token = userStore.getToken
      }
    }
    return config
  },
  (error) => {
    // 这里的错误一般是网络波动造成的， 清空requestMap
    clearRequestMap()
    return Promise.reject(error)
  }
)

// 请求后的统一处理
const whiteReq = ['/xzqh/findByOrgcodeLike.open'] // 总是有那么几个sb接口，后端说做不了统一格式，直接就返回了
service.interceptors.response.use(
  (response) => {
    Toast.clear()

    removeRequestMap(response.config || {}) // 从requestMap对象中移除请求

    const res = response.data
    // 如果是请求的json文件，直接返回res
    if (/(\.json)$/i.test(response.config.url)) {
      return res
    }
    // 不按统一格式返回的sb接口
    if (whiteReq.includes(response.config.url)) {
      return res
    }

    // 返回成功 （res.errcode === 0）
    if (res.errcode === 0) {
      return res
    }
    // 登录过期
    if (res.errcode === 401) {
      const userStore = userStoreCreater()
      showError(res)
      userStore.logOut() //退出
      return Promise.reject({ errcode: -1, errmsg: res.errmsg })
    }

    // 返回错误信息
    showError(res)
    return Promise.reject(res)
  },
  (error) => {
    Toast.clear()
    // 返回的状态不是200
    removeRequestMap(error.config || {}) // 从requestMap对象中移除请求
    if (axios.isCancel(error)) {
      return Promise.reject({
        errcode: -1,
        errmsg: '取消请求',
      })
    }
    const {
      response: { status },
    } = error
    const rejectError = { errcode: -1, errmsg: `服务器异常${status}` }
    showError(rejectError)
    return Promise.reject(rejectError)
  }
)

// 判断错误码errcode
function showError(res) {
  Toast.fail({
    message: res.errmsg,
  })
}

export default service
